﻿#region Class Header
/* ========================================================================
* 【本类功能概述】
* 
* 作者：chinesedragon 
* 时间：4/17/2013 8:33:42 PM
* 文件名：ReleaseDesc
* 版本：V1.0.1
*
* 修改时间： 
* 修改说明：
* ========================================================================
*/
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Collections;
using System.IO;

public class ReleaseList
{
    private string updateDesc = string.Empty;       //发布说明
    private List<ReleaseFile> releaseFiles;                //发布的文件列表
    public string AppName { get; set; }             //发布程序名称
    public string ReleaseVersion { get; set; }      //发布版本
    public string ReleaseDate { get; set; }         //发布日期
    public string StartupExec { get; set; }         //主程序名称
    public string ReleaseUrl { get; set; }          //发布路径
    public string UserName { get; set; }            //发布路径用户名
    public string UserPassword { get; set; }        //发布路径用户密码
    public string SupportUrl { get; set; }          //支持网址
    public string ShortcutIcon { get; set; }        //程序图标

    [XmlIgnore]
    public string ReleaseNote
    {
        get { return updateDesc; }
        set { updateDesc = value; }
    }
    [XmlElement("ReleaseNote")]//注意生成的节点名要同XmlIgnore的名称一致
    public XmlNode TextCData//不要使用XmlCDataSection,否则反序列化会出异常
    {
        get
        {
            return new XmlDocument().CreateCDataSection(updateDesc);
            //注意此处不能写成 this.updateDesc ，否则将会得到null
        }
        set { updateDesc = value.Value; }
    }

    public List<ReleaseFile> Files
    {
        get { return releaseFiles ?? (releaseFiles = new List<ReleaseFile>()); }
        set { releaseFiles = value; }
    }

    public static ReleaseList ReadReleaselist(string filename)
    {
        return XmlSerializeHelper.LoadObjectFromXml<ReleaseList>(filename);
    }

    //public static ReleaseList ReadReleaselist(string filename, string user = "", string pwd = "")
    //{
    //    return XmlSerializeHelper.LoadObjectFromXml<ReleaseList>(filename, user, pwd);
    //}

    public int Compare(ReleaseList otherList)
    {
        if (otherList == null)
            throw new ArgumentNullException("otherList");
        int diff = CompareVersion(otherList.ReleaseVersion);
        if (diff != 0)
            return diff;
        if (ReleaseDate == otherList.ReleaseDate)
            return 0;
        return (DateTime.Parse(ReleaseDate) > DateTime.Parse(otherList.ReleaseDate)) ? 1 : -1;
    }

    private int CompareVersion(string otherVersion)
    {
        return CompareVersion(ReleaseVersion, otherVersion);
    }

    public static int CompareVersion(string thisListVersion, string otherListVersion)
    {
        if (string.IsNullOrEmpty(thisListVersion) || string.IsNullOrEmpty(otherListVersion))
            return 1;
        var thisVersion = thisListVersion.Split('.');
        var otherVersion = otherListVersion.Split('.');
        int nLength = Math.Max(thisVersion.Length, otherVersion.Length);
        for (int i = 0; i < nLength; ++i)
        {
            int thisVer = ConvertToIntVersion(thisVersion, i);
            int otherVer = ConvertToIntVersion(otherVersion, i);
            if (thisVer != otherVer)
                return thisVer - otherVer;
        }
        return 0;
    }

    public static int CompareReleaseDate(string thisDate, string otherDate)
    {
        if (thisDate == otherDate)
            return 0;
        return (DateTime.Parse(thisDate) > DateTime.Parse(otherDate)) ? 1 : -1;
    }

    private static int ConvertToIntVersion(string[] vers, int i)
    {
        if (vers.Length <= i)
            return 0;
        int ver;
        if (!int.TryParse(vers[i], out ver) || ver < 0)
            throw new ArgumentException("Invalid Version Number.");
        return ver;
    }

    public ReleaseFile[] GetDifferenFiles(ReleaseList otherList, out long fileSize)
    {
        fileSize = 0;
        if (otherList == null || Compare(otherList) == 0)
            return null;
        var ht = new Hashtable();
        foreach (ReleaseFile file in releaseFiles)
        {
            ht.Add(file.FileName, file.Version);
        }
        var diff = new List<ReleaseFile>();
        foreach (ReleaseFile file in otherList.releaseFiles)
        {
            if ( (!ht.ContainsKey(file.FileName))        //本地没有此文件
                || ht[file.FileName] == null    //本地虽我此文件，但没有发布日期
                || CompareVersion(file.Version,ht[file.FileName].ToString()) != 0   //两地文件发布日期不一样
            )
            {
                diff.Add(file);
                fileSize += file.FileSize;
            }
        }

        return diff.ToArray();
    }

    //public static void SaveReleaseList(ReleaseList list, string filename)
    //{
    //    string xml = XmlSerializeHelper.GetXmlFromObject(list);
    //    XmlDocument doc = new XmlDocument();
    //    doc.LoadXml(xml);
    //    string dir = Path.GetDirectoryName(filename);
    //    if (!Directory.Exists(dir))
    //        Directory.CreateDirectory(dir);
    //    doc.Save(filename);
    //}
}
